"""
RedFire框架统一DI容器基类

提供所有微服务的标准化基础设施，消除重复实现，实现架构统一。
"""

from dependency_injector import containers, providers
from dependency_injector.wiring import Provide, inject
from typing import Optional, Dict, Any
import logging

from .config import RedFireSettings
from .database import DatabaseManager, DatabaseRouter
from .security import SecurityService
from ..events.manager import EventBusManager
from ..events.bus import EventBus
from ..cache.service import CacheService, create_cache_service_from_settings
from ..middleware.manager import MiddlewareManager

logger = logging.getLogger(__name__)


class RedFireContainer(containers.DeclarativeContainer):
    """
    RedFire框架统一DI容器基类
    
    所有微服务继承此容器，获得标准化的基础设施：
    - 配置管理 (Pydantic Settings)
    - 数据库管理 (统一连接池)
    - 安全服务 (JWT + 密码管理)
    - 日志记录 (结构化日志)
    
    消除"独立王国"模式，实现"联邦体系"架构。
    """
    
    # 配置提供者 - 统一配置管理
    config = providers.Configuration()
    
    # 核心基础设施提供者
    # 数据库管理器 - 单例模式防止资源泄漏，支持向后兼容的配置格式
    # 注意：这里需要在create_for_service中动态设置，因为需要调用settings.get_database_configs()
    database_manager = providers.Singleton(
        DatabaseManager,
        databases_config=config.database
    )
    
    # 数据库路由器 - 提供智能路由功能
    database_router = providers.Singleton(
        DatabaseRouter,
        db_manager=database_manager
    )
    
    security_service = providers.Singleton(
        SecurityService,
        config.security
    )
    
    # 日志服务
    logger_service = providers.Singleton(
        logging.getLogger,
        "redfire"
    )
    
    # 事件总线管理器
    event_bus_manager = providers.Singleton(
        EventBusManager
    )
    
    # 事件总线 - 通过管理器创建，避免全局状态
    event_bus = providers.Factory(
        lambda manager, service_name: manager.get_or_create_bus(service_name),
        manager=event_bus_manager,
        service_name=config.service_name
    )
    
    # 缓存服务 - 统一的缓存管理
    cache_service = providers.Singleton(
        create_cache_service_from_settings,
        config
    )
    
    # 中间件管理器 - 注入事件总线
    middleware_manager = providers.Singleton(
        MiddlewareManager,
        event_bus=event_bus
    )
    
    # 生命周期管理配置 - 由子类覆盖
    # wiring_config 在需要时动态创建
    
    @classmethod
    def create_for_service(
        cls, 
        service_name: str, 
        settings: RedFireSettings,
        database_configs: Optional[Dict[str, Dict[str, Any]]] = None,
        additional_modules: Optional[list] = None
    ) -> "RedFireContainer":
        """
        为特定微服务创建配置好的容器实例
        
        Args:
            service_name: 微服务名称
            settings: 服务配置
            database_configs: 服务特定的数据库配置字典
            additional_modules: 额外的wiring模块
            
        Returns:
            配置完成的容器实例
        """
        # 创建容器实例 - 使用直接实例化避免动态容器问题
        if cls == RedFireContainer:
            container = RedFireContainer()
        else:
            # 对于子类，直接实例化
            container = cls()
        
        # 基础配置
        base_config = {
            "service_name": service_name,
            "security": {
                "jwt_secret_key": settings.jwt_secret_key,
                "jwt_algorithm": settings.jwt_algorithm,
                "jwt_expire_minutes": getattr(settings, 'jwt_expire_minutes', 30)
            }
        }
        
        # 数据库配置处理 - 支持多种配置来源
        if database_configs:
            base_config["database"] = database_configs
        elif hasattr(settings, 'get_database_configs'):
            # 如果settings实现了数据库配置Mixin
            base_config["database"] = settings.get_database_configs()
        elif hasattr(settings, 'database_url'):
            # 向后兼容：扁平格式配置
            base_config["database"] = {
                "url": settings.database_url,
                "pool_size": getattr(settings, 'database_pool_size', 10),
                "echo": getattr(settings, 'database_echo', False)
            }
        else:
            # 没有数据库配置，创建空配置（DatabaseManager会处理）
            base_config["database"] = {}
        
        container.config.from_dict(base_config)
        
        # 配置wiring模块
        if additional_modules:
            container.wire(modules=additional_modules)
        
        logger.info(f"RedFire容器已为服务 '{service_name}' 创建并配置")
        return container
    
    def initialize_resources(self) -> None:
        """初始化容器资源（已废弃，保留向后兼容）"""
        logger.warning("initialize_resources方法已废弃，所有资源在依赖注入时自动初始化")
        try:
            # 验证核心服务可用性
            db_manager = self.database_manager()
            security = self.security_service()
            event_bus = self.event_bus()
            middleware_mgr = self.middleware_manager()
            
            logger.info("RedFire容器资源验证完成")
            
        except Exception as e:
            logger.error(f"容器资源验证失败: {e}")
            raise
    
    async def cleanup_resources(self) -> None:
        """清理容器资源"""
        try:
            # 清理缓存服务
            try:
                cache_service = self.cache_service()
                await cache_service.close()
                logger.info("缓存服务已关闭")
            except Exception as e:
                logger.warning(f"缓存服务清理失败: {e}")
            
            # 清理数据库连接
            try:
                db_manager = self.database_manager()
                if hasattr(db_manager, 'close_all'):
                    await db_manager.close_all()
                logger.info("数据库连接已关闭")
            except Exception as e:
                logger.warning(f"数据库清理失败: {e}")
            
            logger.info("RedFire容器资源清理完成")
            
        except Exception as e:
            logger.error(f"容器资源清理失败: {e}")
            raise


class ServiceContainerMixin:
    """
    微服务容器混入类
    
    提供标准的容器生命周期管理方法
    """
    
    def wire_container(self) -> None:
        """连接容器到应用模块"""
        if hasattr(self, 'wire'):
            self.wire(modules=self.wiring_config.modules)
            logger.info(f"容器已连接到模块: {self.wiring_config.modules}")
    
    def unwire_container(self) -> None:
        """断开容器连接"""
        if hasattr(self, 'unwire'):
            self.unwire()
            logger.info("容器连接已断开")


# 便利函数，用于快速创建标准容器
def create_service_container(
    service_name: str,
    settings: RedFireSettings,
    additional_providers: Optional[Dict[str, Any]] = None,
    additional_modules: Optional[list] = None
) -> RedFireContainer:
    """
    快速创建微服务容器的便利函数
    
    Args:
        service_name: 服务名称
        settings: 服务配置
        additional_providers: 额外的提供者
        additional_modules: 额外的wiring模块
        
    Returns:
        配置完成的容器
    """
    
    # 动态创建容器类
    class ServiceContainer(RedFireContainer, ServiceContainerMixin):
        pass
    
    # 添加额外的提供者
    if additional_providers:
        for name, provider in additional_providers.items():
            setattr(ServiceContainer, name, provider)
    
    # 创建并配置容器
    container = ServiceContainer.create_for_service(
        service_name=service_name,
        settings=settings,
        additional_modules=additional_modules
    )
    
    return container
